/*
 * Copyright (C), 2002-2015, 苏宁易购电子商务有限公司
 * FileName: ComponentAction.java
 * Author:   admin
 * Date:     2015年12月24日 上午9:51:30
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.suning.app.snpaasadmin.action;

import com.opensymphony.xwork2.ActionSupport;
import com.suning.app.snpaasadmin.api.ComponentApi;
import com.suning.app.snpaasadmin.api.LogApi;
import com.suning.app.snpaasadmin.domain.ComponentDetail;
import com.suning.app.snpaasadmin.domain.ComponentInfo;
import com.suning.app.snpaasadmin.operation.CfClusterDBOperation;
import com.suning.app.snpaasadmin.pojo.CfCluster;
import com.suning.app.snpaasadmin.pojo.CfMysqlCluster;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.ws.rs.core.Context;

import org.apache.http.HttpHost;
import org.apache.http.protocol.HttpContext;
import org.apache.struts2.ServletActionContext;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * 组件查看、组件日志相关操作
 * 
 *
 * @author admin
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Controller
public class ComponentAction extends ActionSupport {

    private static final long serialVersionUID = 1L;
    
    private Logger logger = Logger.getLogger(ComponentAction.class);

    @Autowired
    private CfClusterDBOperation clusterDBOperation;

    private Map<String, Object> dataMap;

    private Map<String, Object> tasks;

    private Integer taskId;

    private String deployName;

    private String component;

    private Integer index;

    private String deployId;

    private String operation;

    private String mysqlClusterId;

    /**
     * 
     * 功能描述: <br>
     * bosh组件查看
     *
     * @param deployName
     * @return
     * @throws Exception
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String getBoshComponentState() throws Exception {
        dataMap = new HashMap<String, Object>();
        List<ComponentInfo> comState = new ArrayList<ComponentInfo>();
        // 获得所有的deployments
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpContext httpContext = (HttpContext) session.getAttribute(LoginAction.CFBASICAUTH);
        HttpHost httpHost = (HttpHost) session.getAttribute(LoginAction.CFAUTHHOST);
        Map<String, Object> vms = ComponentApi.getVms(httpContext, httpHost, deployName);
        // 根据taskId获取到状态
        taskId = (Integer) vms.get("id");
        boolean flag = false;
        while (!flag) {
            tasks = ComponentApi.getTasks(httpContext, httpHost, taskId);
            if (tasks.get("state").toString().equals("done")) {
                flag = true;
            }
        }
        // 如果状态是done,才可进行（即flag是true）。taskid为上一个接口返回值中的id
        if (flag == true) {
            comState = ComponentApi.getComponents(httpContext, httpHost, taskId);
        }
        dataMap.put("data", comState);
        dataMap.put("success", true);
        return SUCCESS;
    }

    /**
     * 
     * 功能描述: <br>
     * 组件查看
     *
     * @param deployId
     * @return
     * @throws Exception
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String getComponentState() throws Exception {
        dataMap = new HashMap<String, Object>();
        List<ComponentInfo> comState = new ArrayList<ComponentInfo>();
        // 获得所有的deployments
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpContext httpContext = (HttpContext) session.getAttribute(LoginAction.CFBASICAUTH);
        HttpHost httpHost = (HttpHost) session.getAttribute(LoginAction.CFAUTHHOST);

        // 从数据库中获得deployName
        String name = clusterDBOperation.getDeployName(deployId);
        Map<String, Object> vms = ComponentApi.getVms(httpContext, httpHost, name);
        // 根据taskId获取到状态
        taskId = (Integer) vms.get("id");
        boolean flag = false;
        while (!flag) {
            tasks = ComponentApi.getTasks(httpContext, httpHost, taskId);
            if (tasks.get("state").toString().equals("done")) {
                flag = true;
            }
        }
        // 如果状态是done,才可进行（即flag是true）。taskid为上一个接口返回值中的id
        if (flag == true) {
            comState = ComponentApi.getComponents(httpContext, httpHost, taskId);
            Map<String, Object> tmpMap = new HashMap<>();
            // 遍历
            if (comState != null && comState.size() > 0) {
                for (ComponentInfo componentInfo : comState) {
                    if (tmpMap.containsKey(componentInfo.getName())) {
                        ComponentInfo tmpInfo = (ComponentInfo) tmpMap.get(componentInfo.getName());
                        tmpInfo.setAmount(tmpInfo.getAmount() + 1);
                        tmpInfo.setCpuUsage(new BigDecimal(
                                tmpInfo.getCpuUsage() + componentInfo.getCpuUsage() / tmpInfo.getAmount() + 1)
                                        .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                        tmpInfo.setMemoryUsage(new BigDecimal(
                                tmpInfo.getCpuUsage() + componentInfo.getMemoryUsage() / tmpInfo.getAmount() + 1)
                                        .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                        if (componentInfo.getStatus().equals(1) && tmpInfo.getStatus().equals(1)) {
                            tmpInfo.setStatus(1);
                        } else {
                            tmpInfo.setStatus(0);
                        }
                        tmpMap.put(componentInfo.getName(), tmpInfo);
                    } else {
                        tmpMap.put(componentInfo.getName(), componentInfo);
                    }
                }
                comState.clear();
                for (Object value : tmpMap.values()) {
                    comState.add((ComponentInfo) value);
                }
            }
        }
        dataMap.put("data", comState);
        dataMap.put("success", true);
        return SUCCESS;
    }

    /**
     * 
     * 功能描述: <br>
     * bosh组件日志下载
     *
     * @return
     * @throws Exception
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String boshLogDownload(@Context HttpServletResponse servletResponse) throws Exception {
        dataMap = new HashMap<String, Object>();
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpContext httpContext = (HttpContext) session.getAttribute(LoginAction.CFBASICAUTH);
        HttpHost httpHost = (HttpHost) session.getAttribute(LoginAction.CFAUTHHOST);
        Map<String, Object> tasks = LogApi.getLogTaskId(httpContext, httpHost, deployName, component, index);
        Integer taskId = (Integer) tasks.get("id");
        Map<String, Object> resources = new HashMap<String, Object>();
        boolean flag = false;
        while (!flag) {
            resources = LogApi.getLogResourceId(httpContext, httpHost, taskId);
            if (tasks.get("state").toString().equals("done")) {
                flag = true;
            }
        }
        if (flag == true && resources != null) {
            String resultId = (String) resources.get("result");
            LogApi.downloadLog(httpContext, httpHost, resultId, deployName);
        }
        return SUCCESS;
    }

    /**
     * 
     * 功能描述: <br>
     * 组件日志下载 /rest/componetLog/download
     *
     * @param deployId, component, index
     * @return
     * @throws Exception
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String logDownload() throws Exception {
        dataMap = new HashMap<String, Object>();
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpContext httpContext = (HttpContext) session.getAttribute(LoginAction.CFBASICAUTH);
        HttpHost httpHost = (HttpHost) session.getAttribute(LoginAction.CFAUTHHOST);

        String name = clusterDBOperation.getDeployName(deployId);
        Map<String, Object> tasks = LogApi.getLogTaskId(httpContext, httpHost, name, component, index);
        Integer taskId = (Integer) tasks.get("id");
        Map<String, Object> resources = new HashMap<String, Object>();
        boolean flag = false;
        while (!flag) {
            resources = LogApi.getLogResourceId(httpContext, httpHost, taskId);
            if (resources.get("state").toString().equals("done")) {
                flag = true;
            }
        }
        if (flag == true && resources != null) {
            String resultId = (String) resources.get("result");
            LogApi.downloadLog(httpContext, httpHost, resultId, deployName);
        }
        dataMap.put("success", true);
        return SUCCESS;
    }

    public String componentDetail() throws Exception {
        dataMap = new HashMap<String, Object>();
        List<ComponentDetail> comState = new ArrayList<ComponentDetail>();
        // 获得所有的deployments
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpContext httpContext = (HttpContext) session.getAttribute(LoginAction.CFBASICAUTH);
        HttpHost httpHost = (HttpHost) session.getAttribute(LoginAction.CFAUTHHOST);

        // 从数据库中获得deployName
        String name = clusterDBOperation.getDeployName(deployId);
        Map<String, Object> vms = ComponentApi.getVms(httpContext, httpHost, name);
        // 根据taskId获取到状态
        taskId = (Integer) vms.get("id");
        boolean flag = false;
        while (!flag) {
            tasks = ComponentApi.getTasks(httpContext, httpHost, taskId);
            if (tasks.get("state").toString().equals("done")) {
                flag = true;
            }
        }
        // 如果状态是done,才可进行（即flag是true）。taskid为上一个接口返回值中的id
        if (flag == true) {
            comState = ComponentApi.getComponentDetails(httpContext, httpHost, taskId, component);

            // 循环遍历查询cpu核数
            for (ComponentDetail detail : comState) {
                Integer cpuCore = clusterDBOperation.getCpuCore(component, deployId);
                detail.setCpuCore(cpuCore);
            }
        }
        dataMap.put("data", comState);
        dataMap.put("success", true);
        return SUCCESS;
    }

    public String operateOneComponent() throws Exception {
        dataMap = new HashMap<String, Object>();
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpContext httpContext = (HttpContext) session.getAttribute(LoginAction.CFBASICAUTH);
        HttpHost httpHost = (HttpHost) session.getAttribute(LoginAction.CFAUTHHOST);

        // 根据deployId,获得filePath
        CfCluster cfCluster = clusterDBOperation.selectCfCluster(deployId);
        String filePath = cfCluster.getFilePath();
        String taskId = ComponentApi.operateComponent(httpContext, httpHost, cfCluster.getClusterName(), component,
                index, operation, filePath);
        Map<String, String> map = new HashMap<>();
        map.put("taskId", taskId);
        dataMap.put("data", map);
        dataMap.put("success", true);
        return SUCCESS;
    }

    /**
     * 
     * 功能描述: <br>
     * 数据库组件监控
     *
     * @return
     * @throws Exception
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String getMysqlComponent() throws Exception {
        dataMap = new HashMap<String, Object>();
        List<ComponentInfo> comState = new ArrayList<ComponentInfo>();

        // 获得所有的deployments
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpContext httpContext = (HttpContext) session.getAttribute(LoginAction.CFBASICAUTH);
        HttpHost httpHost = (HttpHost) session.getAttribute(LoginAction.CFAUTHHOST);

        // 从数据库中获得所有的mysql deployName
        CfMysqlCluster mysqlCluster = clusterDBOperation.selectMysqlCluster(mysqlClusterId);
        Map<String, Object> vms = ComponentApi.getVms(httpContext, httpHost, mysqlCluster.getClusterName());

        // 根据taskId获取到状态
        taskId = (Integer) vms.get("id");
        boolean flag = false;
        while (!flag) {
            tasks = ComponentApi.getTasks(httpContext, httpHost, taskId);
            if (tasks.get("state").toString().equals("done")) {
                flag = true;
            }
        }

        // 如果状态是done,才可进行（即flag是true）。taskid为上一个接口返回值中的id
        if (flag == true) {
            comState = ComponentApi.getComponents(httpContext, httpHost, taskId);
            Map<String, Object> tmpMap = new HashMap<>();

            // 遍历
            if (comState != null && comState.size() > 0) {
                for (ComponentInfo componentInfo : comState) {
                    if (tmpMap.containsKey(componentInfo.getName())) {
                        ComponentInfo tmpInfo = (ComponentInfo) tmpMap.get(componentInfo.getName());
                        tmpInfo.setAmount(tmpInfo.getAmount() + 1);
                        tmpInfo.setCpuUsage(new BigDecimal(
                                tmpInfo.getCpuUsage() + componentInfo.getCpuUsage() / tmpInfo.getAmount() + 1)
                                        .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                        tmpInfo.setMemoryUsage(new BigDecimal(
                                tmpInfo.getCpuUsage() + componentInfo.getMemoryUsage() / tmpInfo.getAmount() + 1)
                                        .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                        if (componentInfo.getStatus().equals(1) && tmpInfo.getStatus().equals(1)) {
                            tmpInfo.setStatus(1);
                        } else {
                            tmpInfo.setStatus(0);
                        }
                        tmpMap.put(componentInfo.getName(), tmpInfo);
                    } else {
                        tmpMap.put(componentInfo.getName(), componentInfo);
                    }
                }
                comState.clear();
                for (Object value : tmpMap.values()) {
                    comState.add((ComponentInfo) value);
                }
            }
        }
        dataMap.put("data", comState);
        dataMap.put("success", true);
        return SUCCESS;
    }

    public String monitorMysqlCom() throws Exception {
        dataMap = new HashMap<String, Object>();
        List<ComponentDetail> comState = new ArrayList<ComponentDetail>();
        // 获得所有的deployments
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpContext httpContext = (HttpContext) session.getAttribute(LoginAction.CFBASICAUTH);
        HttpHost httpHost = (HttpHost) session.getAttribute(LoginAction.CFAUTHHOST);

        // 从数据库中获得deployName
        CfMysqlCluster mysqlCluster = clusterDBOperation.selectMysqlCluster(mysqlClusterId);
        Map<String, Object> vms = ComponentApi.getVms(httpContext, httpHost, mysqlCluster.getClusterName());
        // 根据taskId获取到状态
        taskId = (Integer) vms.get("id");
        boolean flag = false;
        while (!flag) {
            tasks = ComponentApi.getTasks(httpContext, httpHost, taskId);
            if (tasks.get("state").toString().equals("done")) {
                flag = true;
            }
        }
        // 如果状态是done,才可进行（即flag是true）。taskid为上一个接口返回值中的id
        if (flag == true) {
            comState = ComponentApi.getComponentDetails(httpContext, httpHost, taskId, component);

            // 循环遍历查询cpu核数
            for (ComponentDetail detail : comState) {
                Integer cpuCore = clusterDBOperation.getMysqlCpuCore(component, mysqlClusterId);
                detail.setCpuCore(cpuCore);
            }
        }
        dataMap.put("data", comState);
        dataMap.put("success", true);
        return SUCCESS;
    }
    
    public InputStream getMysqlLogDownload() throws Exception {
        dataMap = new HashMap<String, Object>();
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpContext httpContext = (HttpContext) session.getAttribute(LoginAction.CFBASICAUTH);
        HttpHost httpHost = (HttpHost) session.getAttribute(LoginAction.CFAUTHHOST);

        CfMysqlCluster mysqlCluster = clusterDBOperation.selectMysqlCluster(mysqlClusterId);
        Map<String, Object> tasks = LogApi.getLogTaskId(httpContext, httpHost, mysqlCluster.getClusterName(), component, index);
        Integer taskId = (Integer) tasks.get("id");
        Map<String, Object> resources = new HashMap<String, Object>();
        boolean flag = false;
        File file = null;
        while (!flag) {
            resources = LogApi.getLogResourceId(httpContext, httpHost, taskId);
            if (resources.get("state").toString().equals("done")) {
                flag = true;
            }
        }
        if (flag == true && resources != null) {
            String resultId = (String) resources.get("result");
            file = LogApi.downloadLog(httpContext, httpHost, resultId, mysqlCluster.getClusterName());
        }
        setFilename(file.getName());
        return new FileInputStream(file);
    }
    
    private String filename;

    public InputStream getDownloadLog() throws Exception {
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpContext httpContext = (HttpContext) session.getAttribute(LoginAction.CFBASICAUTH);
        HttpHost httpHost = (HttpHost) session.getAttribute(LoginAction.CFAUTHHOST);
        String name = clusterDBOperation.getDeployName(deployId);
        Map<String, Object> tasks = LogApi.getLogTaskId(httpContext, httpHost, name, component, index);
        Integer taskId = (Integer) tasks.get("id");
        Map<String, Object> resources = new HashMap<String, Object>();
        File file = null;
        boolean flag = false;
        while (!flag) {
            resources = LogApi.getLogResourceId(httpContext, httpHost, taskId);
            if (resources.get("state").toString().equals("done")) {
                flag = true;
            }
        }
        if (flag == true && resources != null) {
            String resultId = (String) resources.get("result");
            file = LogApi.downloadLog(httpContext, httpHost, resultId, name);
        }
        try {
            setFilename(file.getName());
            return new FileInputStream(file);
        } finally {
            boolean isDelete = file.delete();
            logger.fatal("删除文件："+isDelete);
        }
    }

    public void setFilename(String filename) {
        try {
            this.filename = new String(filename.getBytes("ISO8859-1"), "GBK");
        } catch (UnsupportedEncodingException e) {
        }
    }

    public String getFilename() {
        try {
            return new String(filename.getBytes(), "ISO8859-1");
        } catch (UnsupportedEncodingException e) {
            return this.filename;
        }
    }

    /**
     * @return the dataMap
     */
    public Map<String, Object> getDataMap() {
        return dataMap;
    }

    public void setDataMap(Map<String, Object> dataMap) {
        this.dataMap = dataMap;
    }

    /**
     * @return the deployName
     */
    public String getDeployName() {
        return deployName;
    }

    /**
     * @param deployName the deployName to set
     */
    public void setDeployName(String deployName) {
        this.deployName = deployName;
    }

    /**
     * @return the index
     */
    public Integer getIndex() {
        return index;
    }

    /**
     * @param index the index to set
     */
    public void setIndex(Integer index) {
        this.index = index;
    }

    /**
     * @return the component
     */
    public String getComponent() {
        return component;
    }

    /**
     * @param component the component to set
     */
    public void setComponent(String component) {
        this.component = component;
    }

    /**
     * @return the deployId
     */
    public String getDeployId() {
        return deployId;
    }

    /**
     * @param deployId the deployId to set
     */
    public void setDeployId(String deployId) {
        this.deployId = deployId;
    }

    /**
     * @return the operation
     */
    public String getOperation() {
        return operation;
    }

    /**
     * @param operation the operation to set
     */
    public void setOperation(String operation) {
        this.operation = operation;
    }

    /**
     * @return the mysqlClusterId
     */
    public String getMysqlClusterId() {
        return mysqlClusterId;
    }

    /**
     * @param mysqlClusterId the mysqlClusterId to set
     */
    public void setMysqlClusterId(String mysqlClusterId) {
        this.mysqlClusterId = mysqlClusterId;
    }

}
